#pragma once

#include <iostream>
#include <string>
#include <cstring>
#include <jsoncpp/json/json.h>
#include "log.hpp"

//#define Myself

const std::string space_sep = " ";
const std::string protocal_sep = "\n";

// len/n x + y/n;
std::string Encode(std::string &context)
{
    std::string s = std::to_string(context.size());
    s += protocal_sep;
    s += context;
    s += protocal_sep;

    return s;
}
// len/n x + y/n;
bool Decode(std::string &package, std::string *context)
{
    auto pos = package.find(protocal_sep);
    if (pos == std::string::npos)
        return false;
    std::string len_str = package.substr(0, pos); //len 
    std::size_t len = std::stoi(len_str);
    int total_len = len + len_str.size() + 2;
    if (package.size() < total_len)
        return false;
    
    *context = package.substr(pos + 1, len);
    
    //移除解码数据
    package.erase(0,total_len);
    return true;
}

class Requset
{
public:
    Requset(int data1, char op, int data2)
        : x_(data1), op_(op), y_(data2)
    {
    }

    Requset()
    {
    }

    ~Requset()
    {
        
    }
    void Print()
    {
        std::cout << x_ << op_ << y_ << std::endl;
    }
    // 序列化：x + y
    bool Serialize(std::string *out)
    {
#ifdef Myself
        // 构建有效载荷
        std::string s = std::to_string(x_);
        s += space_sep;
        s += op_;
        s += space_sep;
        s += std::to_string(y_);

        *out = s;
        return true;
#else
        Json::Value root;
        root["x"] = x_;
        root["y"] = y_;
        root["op"] = op_;

        Json::FastWriter w;
        *out = w.write(root);

        return true;
        
#endif
        
    }

    // 反序列化 x + y
    bool Deserialize(const std::string &in)
    {
#ifdef Myself
        // 解析有效载荷
        auto pos1 = in.find(space_sep);
        if (pos1 == std::string::npos)
            return false;

        std::string part_x = in.substr(0, pos1);
        auto pos2 = in.rfind(space_sep);

        std::string oper = in.substr(pos1 + 1, pos2);
        std::string part_y = in.substr(pos2 + 1);
        if (pos2 != pos1 + 2)
            return false;

        op_ = in[pos1 + 1];
        x_ = std::stoi(part_x);
        y_ = std::stoi(part_y);

        return true;
#else

        Json::Value root;
        Json::Reader r;
        r.parse(in,root);

        root["x"].asInt();
        root["y"].asInt();
        root["op"].asString();

        return true;
#endif

    }

    int Getx()
    {
        return x_;
    }

    int Gety()
    {
        return y_;
    }

    char Getop()
    {
        return op_;
    }


    int x_;
    char op_;
    int y_;
};

class Response
{
public:
    Response(int ret, int code)
        : result_(ret), code_(code)
    {
    }

    Response()
    {}

    ~Response()
    {
    }

    // 序列化  r code
    bool Serialize(std::string *out)
    {
#ifdef Myself
        // 构建有效载荷
        std::string s = std::to_string(result_);
        s += space_sep;
        s += std::to_string(code_);
        *out = s;


        return true;

#else
        Json::Value root;
        root["result"] = result_;
        root["code"] = code_;

        Json::FastWriter w;
        *out = w.write(root);
        return true;

#endif

    }

    bool Deserialize(const std::string &in)
    {

#ifdef Myself
        auto pos = in.find(space_sep);
        std::string res = in.substr(0, pos);
        //std::cout << "++++++++ res:" << res << std::endl;
        std::string code = in.substr(pos + 1);
        //std::cout << "++++++++ code:" << res << std::endl;

        if (pos != in.rfind(space_sep))
            return false;

        result_ = std::stoi(res);
        code_ = std::stoi(code);
        return true;

#else

    Json::Value root;
    Json::Reader r;
    r.parse(in,root);

    root["result"].asInt();
    root["code"].asInt();

    return true;

#endif
    }

    void Print()
    {
        std::cout << "result_: " << result_ << " code_: " << code_<< std::endl;
    }


    int result_;
    int code_;

};
